#include "CCmdDropItem.h"
#include "../item/CItemMgr.h"
#include "../storage/CStorageMgr.h"
#include "../equip/CEquipMgr.h"
#include "../partner/CPartnerMgr.h"
#include "../cmd/dataprepare.h"
#include "../mainctrl.h"
#include "commmsg.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_DROP_ITEM , CCmdDropItem);

int CCmdDropItem::Do(void* pData)
{
    if (pData != NULL)
    {
        CT_WARNING(("inner cmd CCmdDropItem get data"));
        return Done(RET_OK);
    }

    if (pstMainCtrl == NULL)
    {
        CT_ERROR(("mainctrl point is null"));
        return Done(RET_SYSTEM_FAIL);
    }

    if (stDropItem._astDropItem.Size() <= 0)
    {
        CT_WARNING(("drop item do nothing"));
        return Done(RET_OK);
    }

    if (uiGID == 0)
    {
        CT_ERROR(("drop item uiGID error %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdDropItem::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        CT_ERROR(("drop item error , ret %d", iRet));
        return Done(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_EX1_INFO(uiGID);

    PREPARE_PLAYER_SNS_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_ONLINE_DATA (this, uiGID);
    PREPARE_UNACT_PARTNER_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user base info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail ex1 info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user sns detail info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerSnsDetailInfo& stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];
    CPlayerStatic& stPlayerStatic = stPlayerSnsDetailInfo._stMyInfo._stPlayerStatic;

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
            CT_ERROR(("get user online info error, uid = %u", uiGID));
            return Done(RET_SYS_ERROR);
        }
        CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    iIndex = pstMainCtrl->m_stUnactPartnerInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user unact partner info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CUnactPartnerInfo& stUnactPartnerInfo = pstMainCtrl->m_stUnactPartnerInfoHash[iIndex];

    iIndex = pstMainCtrl->FindPlayerCacheData(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user cache data error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
	CPlayerCacheData& stPlayerCache = pstMainCtrl->m_stPlayerCacheDataHash[iIndex];

    int iNowTime = pstMainCtrl->m_iNow;

    pstMainCtrl->m_stOssMgr.ClearKeyValueList();//oss
    //准备数据结束

    //添加物品
    unsigned int uiNotifyType = 0;
    CDropItem stBagNewItem;   //通知前台背包新获得的物品
    for (int i = 0; i < stDropItem._astDropItem.Size(); ++i)
    {
        CDropItemData& stDropItemData = stDropItem._astDropItem[i];
        if (stDropItemData._iItemCount <= 0)
        {
            continue;
        }

        CT_TRACE(("%d, %d, %d, %d, %d, %d", uiGID, stDropItem._iModule, stDropItemData._ucItemType, 
                  stDropItemData._usItemConfigID, stDropItemData._iItemCount, stDropItemData._iData1));

        switch(stDropItemData._ucItemType)
        {
        case ITEM_TYPE_EQUIP:
            {
                for (int k = 0; k < stDropItemData._iItemCount; k++)
                {
                    unsigned int uiEquipID = 0;
                    iRet = pstMainCtrl->m_stEquipMgr.AddEquip(stPlayerOnlineData._stUserEquip, stDropItemData._usItemConfigID, stPlayerOnlineData._stUserStorage, uiEquipID);
                    if (iRet == ERROR_STORAGE_BAG_IS_FULL)
                    {
                        stLeftItem._astDropItem.AddOneItem(stDropItemData);
                    }

                    if (RET_OK == iRet)
                    {                    
                        stDropItemData._iData1 = uiEquipID; //保存装备ID
                        stBagNewItem.Drop(stDropItemData);
                    }
                    else
                    {
                        CT_ERROR(("add equip to user %u error, %d, %d, %d, %d",
                            uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID,
                            stDropItemData._iItemCount, iRet));
                    }
                }
            }
            break;
        case ITEM_TYPE_LEVEL_EXP:
            {
                CDropItemData stDropItemTmp;
                iRet = pstMainCtrl->m_stItemMgr.GetDropItemData(uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, "", COMM_MOD, stDropItemData._iItemCount, stDropItemTmp);
                if (RET_OK == iRet)
                {
                    stDropItemData._ucItemType = stDropItemTmp._ucItemType;
                    stDropItemData._usItemConfigID = stDropItemTmp._usItemConfigID;
                    stDropItemData._iItemCount = stDropItemTmp._iItemCount;
                }
                else
                {
                    CT_WARNING(("GetDropItemData error, %u, %d, %d, %d",
                                uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));
                    break;
                }
            }
        case ITEM_TYPE_EXP:
        case ITEM_TYPE_CLAN_EXP:
            {
                bool bSendTeamFighting = false;
                short shOldLevel = stPlayerBaseInfo._shLevel;
                //主角经验
                iRet = pstMainCtrl->m_stRoleMgr.RoleAddExp(stPlayerBaseInfo,
                    stPlayerDetailInfo, stPlayerOnlineData,
                    stPlayerDetailEx1Info, stDropItemData._iItemCount);
                if (iRet)
                {
                    CT_WARNING(("RoleAddExp gid: %d ,type: %d, count: %d, error",
                        uiGID, stDropItemData._ucItemType, stDropItemData._iItemCount));
                    continue;
                }

                stPlayerSnsDetailInfo._stCommInfo._usLevel = stPlayerBaseInfo._shLevel;
                stPlayerSnsDetailInfo._stCommInfo._i64NowExp = stPlayerBaseInfo._i64NowExp;

                HandleLevelUp(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData, stPlayerDetailEx1Info, stPlayerSnsDetailInfo, shOldLevel);

                if (stPlayerBaseInfo._shLevel > shOldLevel)
                {
                    bSendTeamFighting = true;
                }

                if (stPlayerBaseInfo._ucIsInited != 1)
                {
                    continue;//角色未初始化职业 不应操作阵型数据
                }

                //伙伴经验
				char chMainMatrix = stPlayerDetailInfo._stPlayerMatrix._chMainMatrix;
                if (chMainMatrix < 0 ||
                    chMainMatrix >= stPlayerDetailInfo._stPlayerMatrix._astMatrixData.Size())
                {
                    CT_ERROR(("role(%u) main matrix index(%d) error matrix size(%d)",
                              stPlayerDetailInfo._uiGID,chMainMatrix,
                              stPlayerDetailInfo._stPlayerMatrix._astMatrixData.Size()));
                    continue;
                }

                short shOldPartnerLvl = 0;
				CMatrixList& stMatrixList = stPlayerDetailInfo._stPlayerMatrix._astMatrixData[chMainMatrix];
				for (int i = 0; i < stMatrixList._astMatrixList.Size(); ++i)
				{
					if (GAME_OBJ_TYPE_PARTNER != stMatrixList._astMatrixList[i]._chType)
					{
						continue;
					}
					iIndex = stPlayerDetailInfo._stUserPartner.FindActData((short)stMatrixList._astMatrixList[i]._uiID);
					if (iIndex < 0)
					{
						CT_BATTLE(("Can find matrix(%d) partner(%d)",
									stPlayerDetailInfo._stPlayerMatrix._chMainMatrix,
									(short)stMatrixList._astMatrixList[i]._uiID));
						continue;
					}
					CPartnerActData& stActData = stPlayerDetailInfo._stUserPartner.GetPartnerActData(iIndex);

                    shOldPartnerLvl = stActData._shLevel;
                	iRet = pstMainCtrl->m_stPartnerMgr.PartnerAddExp(stActData._shResID,
                        stDropItemData._iItemCount, stPlayerBaseInfo, stPlayerDetailInfo,
                        stPlayerOnlineData, stPlayerDetailEx1Info);
                    if (iRet)
                    {
                        CT_WARNING(("RoleAddExp gid: %d, resid: %d, type: %d, count: %d, error",
                            uiGID, stActData._shResID, stDropItemData._ucItemType, stDropItemData._iItemCount));
                        continue;
                    }

                    if (stActData._shLevel > shOldPartnerLvl)
                    {
                        bSendTeamFighting = true;
                    }
				}

                uiNotifyType |= (NOTIFY_ROLE_INFO | NOTIFY_PARTNER_EXP);

                stPlayerStatic._stTodayRoleGetExp.Add(stDropItemData._iItemCount, iNowTime);                

                if (bSendTeamFighting)
                {
                    pstMainCtrl->m_stMatrixMgr.SendMatrixFightingToFront(
                        stPlayerBaseInfo, stPlayerDetailInfo,
                        stPlayerOnlineData);
                }
            }
            break;
        case ITEM_TYPE_EXP_ROLE:
            {
                short shOldLevel = stPlayerBaseInfo._shLevel;

                //主角经验
                iRet = pstMainCtrl->m_stRoleMgr.RoleAddExp(stPlayerBaseInfo,
                    stPlayerDetailInfo, stPlayerOnlineData,
                    stPlayerDetailEx1Info, stDropItemData._iItemCount);
                if (iRet)
                {
                    CT_WARNING(("RoleAddExp gid: %d ,type: %d, count: %d, error",
                        uiGID, stDropItemData._ucItemType, stDropItemData._iItemCount));
                    continue;
                }

                stPlayerSnsDetailInfo._stCommInfo._usLevel = stPlayerBaseInfo._shLevel;
                stPlayerSnsDetailInfo._stCommInfo._i64NowExp = stPlayerBaseInfo._i64NowExp;

                HandleLevelUp(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData, stPlayerDetailEx1Info, stPlayerSnsDetailInfo, shOldLevel);

                uiNotifyType |= NOTIFY_ROLE_INFO;
                stPlayerStatic._stTodayRoleGetExp.Add(stDropItemData._iItemCount, iNowTime);

                if (stPlayerBaseInfo._shLevel > shOldLevel)
                {
                    pstMainCtrl->m_stMatrixMgr.SendMatrixFightingToFront(
                        stPlayerBaseInfo, stPlayerDetailInfo,
                        stPlayerOnlineData);
                }
            }
            break;
        case ITEM_TYPE_EXP_PARTNER:
            {
                //伙伴经验
                short shPartnerID = (short)stDropItemData._iData1;
                short shOldPartnerLvl = 0;
				int iIndex = stPlayerDetailInfo._stUserPartner.FindActData(shPartnerID);
                if (iIndex < 0)
                {
                    iIndex = stUnactPartnerInfo.FindListData(shPartnerID);
                    if (iIndex < 0)
                    {
                        CT_WARNING((""));
                        continue;
                    }

                    iRet = pstMainCtrl->m_stPartnerMgr.UnactPartnerAddExp(
                        shPartnerID, stDropItemData._iItemCount,
                        stPlayerBaseInfo, stUnactPartnerInfo);
                }
                else
                {
					CPartnerActData& stActData = stPlayerDetailInfo._stUserPartner.GetPartnerActData(iIndex);
                    shOldPartnerLvl = stActData._shLevel;
                    iRet = pstMainCtrl->m_stPartnerMgr.PartnerAddExp(shPartnerID, stDropItemData._iItemCount,
                        stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData, stPlayerDetailEx1Info);

                    if (pstMainCtrl->m_stMatrixMgr.PartnerInMainMatrix(stPlayerDetailInfo, shPartnerID) &&
                            stActData._shLevel > shOldPartnerLvl)
                    {
                        pstMainCtrl->m_stMatrixMgr.SendMatrixFightingToFront(
                            stPlayerBaseInfo, stPlayerDetailInfo,
                            stPlayerOnlineData);
                    }

                    uiNotifyType |= NOTIFY_PARTNER_EXP;
                }

                if (iRet)
                {
                    CT_WARNING(("ITEM_TYPE_EXP_PARTNER gid: %d, shPartnerID: %d, type: %d, count: %d, error",
                        uiGID, shPartnerID, stDropItemData._ucItemType, stDropItemData._iItemCount));
                    continue;
                }
            }
            break;
        case ITEM_TYPE_LEVEL_SILVER:
            {
                CDropItemData stDropItemTmp;
                iRet = pstMainCtrl->m_stItemMgr.GetDropItemData(uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, "", COMM_MOD, stDropItemData._iItemCount, stDropItemTmp);
                if (RET_OK == iRet)
                {
                    stDropItemData._ucItemType = stDropItemTmp._ucItemType;
                    stDropItemData._usItemConfigID = stDropItemTmp._usItemConfigID;
                    stDropItemData._iItemCount = stDropItemTmp._iItemCount;
                }
                else
                {
                    CT_WARNING(("GetDropItemData error, %u, %d, %d, %d",
                        uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));
                    break;
                }
            }
        case ITEM_TYPE_SILVER:
        case ITEM_TYPE_CLAN_SILVER:
            {
                iRet = CPlayerBaseInfo::AddSilver(stPlayerBaseInfo._i64Silver, stDropItemData._iItemCount);
                if (iRet)
                {
                    CT_ERROR(("drop item %d,%d,%d", stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));
                }                

                uiNotifyType |= NOTIFY_USER_MONEY;
                
                if (stDropItem._iModule != OSS_MODULE_AUCTION)
                {
                    stPlayerStatic._stTodayGetSilver.Add(stDropItemData._iItemCount, iNowTime);
                    pstMainCtrl->m_stAcademyMgr.SilverChange(uiGID, stPlayerStatic._stTodayGetSilver.Get(iNowTime), stPlayerBaseInfo._ucAcademy);
                }
                
            }
            break;
        case ITEM_TYPE_GOLD:
            {
                iRet = CPlayerBaseInfo::AddGold(stPlayerBaseInfo._iGold, stDropItemData._iItemCount);
                if (iRet)
                {
                    CT_ERROR(("drop item %d,%d,%d", stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));
                }
                else
                {
                    pstMainCtrl->m_stOssMgr.TriggerMoney(stPlayerBaseInfo._uiGID, OSS_MONEY_ADD_GOLD,
                                                         stDropItem._iModule, stDropItemData._iItemCount);
                    uiNotifyType |= NOTIFY_USER_MONEY;   

                    //32wan充值记录
                    if (OSS_MODULE_32WAN_ADD_GOLD == stDropItem._iModule)
                    {
                        if (stPlayerBaseInfo._stVipData._iPayGold <= 0)
                        {
                            //记录首充
                            pstMainCtrl->m_stOssMgr.TriggerMoney (uiGID, OSS_MONEY_FIRST_BUY, DEFAULT_GOODS_ID_32WAN, stDropItemData._iItemCount);
                            pstMainCtrl->m_stOssMgr.TriggerFirstPay(uiGID, stDropItemData._iItemCount * 10);
                        }

                        //修改VIP
                        pstMainCtrl->m_stVipMgr.PrepaidGold(stPlayerBaseInfo, stPlayerDetailInfo, 
                                            stDropItemData._iItemCount, true);

                        //活动
                        pstMainCtrl->m_stActMgr.TriggerBuyGoods(stPlayerDetailInfo._stSplendidAct, uiGID, 91, 
                                        stDropItemData._iItemCount, 0, stPlayerBaseInfo._stVipData._iPayGold);
                    }
                }
            }
            break;
        case ITEM_TYPE_HUNLI:
            {
                stPlayerBaseInfo._iHunli += stDropItemData._iItemCount;
                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_LILIAN:
            break;
        case ITEM_TYPE_REPUTATION:
            {
                stPlayerStatic._stTodayGetReputation.Add(stDropItemData._iItemCount, iNowTime);
                pstMainCtrl->m_stAcademyMgr.RepChange(uiGID, stPlayerStatic._stTodayGetReputation.Get(iNowTime), stPlayerBaseInfo._ucAcademy);

                if (0 != stPlayerSnsDetailInfo._stCommInfo._uiClanId)
                {
                    int iToAddContri = stDropItemData._iItemCount/10;                    
                    pstMainCtrl->m_stClanMgr.AddTodayContri (stPlayerSnsDetailInfo, iToAddContri, stDropItemData._iItemCount);
                }

                int iRoleReputationLimit = pstMainCtrl->m_stPartnerMgr.GetRoleReputationLimit();
                if (stPlayerDetailInfo._iReputation >= iRoleReputationLimit)
                {
                    break;//如果声望值大于等于表格配置上限则丢掉 --byronwei
                }
                if (stPlayerDetailInfo._iReputation + stDropItemData._iItemCount > iRoleReputationLimit)
                {
                    stDropItemData._iItemCount = iRoleReputationLimit - stPlayerDetailInfo._iReputation;
                }

                stPlayerDetailInfo._iReputation += stDropItemData._iItemCount;
                stPlayerSnsDetailInfo._stCommInfo._iReputation = stPlayerDetailInfo._iReputation;
                stPlayerSnsDetailInfo._stCommInfo._iRepuChgTime = pstMainCtrl->m_iNow;

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_CONTRIBUTION:
            {
                pstMainCtrl->m_stClanMgr.AddTodayContri (stPlayerSnsDetailInfo, stDropItemData._iItemCount, 0);

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_SPIRIT:
            {
                CPlayerBaseInfo::ChangeIntValue(stPlayerDetailInfo._stTreasureData._iSpirit, stDropItemData._iItemCount);

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_TREASURE:
            {
                if (!pstMainCtrl->m_stTreasureMgr.IsRoleGetTreasure(stDropItemData._usItemConfigID, stPlayerDetailInfo))
                {
                    pstMainCtrl->m_stTreasureMgr.RoleGetTreasure(stDropItemData._usItemConfigID, stPlayerDetailInfo);
                }
            }
            break;

        case ITEM_TYPE_GIFT:
            {
                if (ACT_BONUS_TYPE_AUCTION == stDropItemData._usItemConfigID)  //拍卖会物品
                {
                    if (OSS_MODULE_AUCTION == stDropItem._iModule)
                    {
                        unsigned short usGoodsId = stDropItemData._iData1;
                        if (stPlayerBaseInfo._stUserAuctionData._astPending.Size() >= MAX_AUCTION_PENDING_GOODS)
                        {
                            CT_ERROR(("%d, %d", uiGID, usGoodsId));  //未领取的物品太多了,放不下
                        }
                        else
                        {
                            stPlayerBaseInfo._stUserAuctionData._astPending.AddOneItem(usGoodsId);
                            uiNotifyType |= NOTIFY_BONUS_INFO;

                            //活动触发
                            CAuctionGoodsUnit stGoods;
                            pstMainCtrl->m_stAuctionMgr.GetGoodsConfig(usGoodsId, stGoods);

                            //精彩活动：金秋猎金触发
                            if (stGoods._ucItemType == ITEM_TYPE_CARD2)
                            {
                                CCardConfigData stCardConfigData;
                                CMainCtrl::m_pstMain->m_stCardMgr.GetCardConfig(stGoods._usItemConfigID, stCardConfigData);

                                if (CARD_TYPE_GOLD_CARD == stCardConfigData._ucCardType)
                                {
                                    CMainCtrl::m_pstMain->m_stActMgr.TriggerGetCard(stPlayerDetailInfo._stSplendidAct, 
                                        uiGID, stCardConfigData._ucCardType, stCardConfigData._usCardConfigID, stGoods._shItemCount);
                                }
                            }
                        }
                    }
                    else
                    {
                        CT_ERROR(("wrong auction goods: %d, %d", uiGID, stDropItem._iModule));
                    }
                }
                else
                {
                    //需要领取的奖励礼包
                    iRet = pstMainCtrl->m_stGiftMgr.AddBonusGift (stPlayerDetailInfo, stPlayerOnlineData._stUserStorage, stDropItemData);
                    if (RET_OK == iRet)
                    {
                        if (ADD_GIFT_BAG == stDropItemData._iData1)
                        {
                            stBagNewItem.Drop(stDropItemData);
                        }
                        else
                        {
                            uiNotifyType |=  NOTIFY_BONUS_INFO;
                        }                        
                    }
                    else
                    {
                        CT_ERROR(("%d, %d, %d, %d, %d", iRet, uiGID, stDropItemData._usItemConfigID, stDropItemData._iItemCount, stDropItemData._iData1));
                        stLeftItem.Drop (stDropItemData);
                    }
                }
            }
            break;
        case ITEM_TYPE_LESSON_POINT:
            {
                stPlayerDetailInfo._stUserLessonData._iLessonPoint += stDropItemData._iItemCount;

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_ENERGY:
            {
                stPlayerBaseInfo._stUserEnergy.AddEnergy(stDropItemData._iItemCount, pstMainCtrl->m_iNow);

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;
        case ITEM_TYPE_BLESS_POINT:
            {
                stPlayerDetailInfo._stUserEquip._iBlessPoint += stDropItemData._iItemCount;

                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
            break;

        case ITEM_TYPE_USE_GOLD_POINT: //消费返利点数
            {
                stPlayerDetailEx1Info._stPayActData.AddQPoint(stPlayerBaseInfo._chVipLevel, 
                            stDropItemData._iItemCount, pstMainCtrl->m_iNow);
            }
            break;

        case ITEM_TYPE_MOUNT_SOUL:  // 坐骑骑魂
            {
                pstMainCtrl->m_stMountMgr.AddMountSoul(stPlayerDetailEx1Info._stMount, stDropItemData);
            }
            break;

        case ITEM_TYPE_MANOR_SCORE: //领地战积分
            {
                pstMainCtrl->m_stManorBattleMgr.UpdateRoleInfo(stPlayerCache);
                if (stDropItemData._iItemCount > 0)
                {
                    stPlayerCache._stManorBattleRole.AddScore(
                        stDropItemData._iItemCount);
                }
            }
            break;

        case ITEM_TYPE_CARD:
            stDropItemData._ucItemType = ITEM_TYPE_CARD2;
        default:
            {
                //等级相关物品
                if (pstMainCtrl->m_stItemMgr.IsLevelItem(stDropItemData._ucItemType, stDropItemData._usItemConfigID)) 
                {
                    iRet = pstMainCtrl->m_stItemMgr.GetLevelItem(uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount, stDropItemData);
                    if (iRet)
                    {
                        CT_ERROR(("GetLevelItem user %u error, %d, %d, %d, %d, %d",  uiGID, iRet, stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));

                        continue;
                    }
                }

                CItemConfigData stItemConfigData;
                iRet = pstMainCtrl->m_stItemMgr.GetConfig(stDropItemData._ucItemType, stDropItemData._usItemConfigID, stItemConfigData);
                if (0 != iRet || 0 == stItemConfigData._iUseGrid)
                {
                    CT_ERROR(("%d, %d, %d, %d", uiGID, stDropItemData._ucItemType, stDropItemData._iItemCount, iRet));
                    continue;
                }               

                short shOrgCount = (short)(stDropItemData._iItemCount & 0x7FFF);
                short shLeftCount = shOrgCount;
                iRet = pstMainCtrl->m_stStorageMgr.TryAddItem(stPlayerOnlineData._stUserStorage, stDropItemData._ucItemType,
                                                              stDropItemData._usItemConfigID, shLeftCount);
                if (iRet != 0)
                {
                    if (shLeftCount > 0)
                    {
                        stDropItemData._iItemCount = shLeftCount;
                        stLeftItem.Drop (stDropItemData);
                    }
                    
                    CT_ERROR(("add item to user %u error, %d, %d, %d, %d, %d",
                        uiGID, stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount, shLeftCount, iRet));                    
                }
                else
                {
                    stDropItemData._iItemCount = shOrgCount - shLeftCount;
                    stBagNewItem.Drop(stDropItemData);  
                }              

                //触发任务
                pstMainCtrl->m_stTaskMgr.TriggerGetItem(stPlayerOnlineData._stUserTask, stDropItemData._ucItemType,
                                                        stDropItemData._usItemConfigID, stDropItemData._iItemCount);

                //触发精彩活动
                pstMainCtrl->m_stActMgr.TriggerGetItem(stPlayerDetailInfo._stSplendidAct, uiGID, 
                    stDropItemData._ucItemType,
                    stDropItemData._usItemConfigID, stDropItemData._iItemCount);
                
            }
            break;
        }
    }

    //保存数据
    pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);
    stPlayerOnlineData._stUserTask.GetData(stPlayerBaseInfo._stUserTaskData);
    pstMainCtrl->m_stEquipMgr.GetData(stPlayerOnlineData._stUserEquip, stPlayerDetailInfo._stUserEquip);

    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    stKey.m_u64ID = stPlayerBaseInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    stKey.m_chDataType = DT_PLAYER_SNS_DETAIL_INFO;
    stKey.m_u64ID = stPlayerSnsDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerSnsDetailInfo, VOP_UPDATE);

    stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
    stKey.m_u64ID = stPlayerDetailEx1Info._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailEx1Info, VOP_UPDATE);

    //通知背包中新获得的物品. (家族转盘以及QQ好友邀请转盘获得的物品,不需要通知,前台自行处理)
    if (stBagNewItem.GetSpaceSize() > 0)
    {
        if (OSS_MODULE_CLAN_DIAL != stDropItem._iModule &&
            OSS_MODULE_QQ_FRIEND_DIAL != stDropItem._iModule &&
            OSS_MODULE_FIGHT_END != stDropItem._iModule)
        {
            pstMainCtrl->m_stItemMgr.NotifyDropItem (uiGID, stBagNewItem);
        }
        
        uiNotifyType |= NOTIFY_BAG_INFO;
    }

    //下发数据
    pstMainCtrl->m_stNotifyMgr.Notify(uiGID, uiNotifyType);

    //OSS账单:物品产出与消耗
    pstMainCtrl->m_stOssMgr.TriggerItem(uiGID, OSS_ITEM_DROP);//oss

    return Done(0);
}

void CCmdDropItem::HandleLevelUp (CPlayerBaseInfo & stPlayerBaseInfo, CPlayerDetailInfo & stPlayerDetailInfo,
                                  CPlayerOnlineData& stPlayerOnlineData, CPlayerDetailInfoEx1& stPlayerDetailInfoEx1,
                                  CPlayerSnsDetailInfo & stPlayerSnsDetailInfo, short shOldLevel)
{
    if (shOldLevel == stPlayerBaseInfo._shLevel)
    {
        return ;
    }

    stPlayerBaseInfo._iLevelUpTime = pstMainCtrl->m_iNow;
    stPlayerSnsDetailInfo._stCommInfo._iLevChgTime = pstMainCtrl->m_iNow;

    //判断是否需要发送等级礼包, 是否有等级礼包可用
    HandleLevelGift(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData, shOldLevel);

    //根据主角查看是否可以免费开背包和仓库中的格子
    HandleStorageGrid(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData, shOldLevel);

    //触发任务
    CMainCtrl::m_pstMain->m_stTaskMgr.TriggerLevelUp(stPlayerOnlineData._stUserTask, stPlayerBaseInfo._shLevel);
    stPlayerOnlineData._stUserTask.GetData(stPlayerBaseInfo._stUserTaskData);

    //触发精彩活动
    CMainCtrl::m_pstMain->m_stActMgr.TriggerLevelUp(stPlayerDetailInfo._stSplendidAct, uiGID, stPlayerBaseInfo._shLevel);

    //触发新手任务
    CMainCtrl::m_pstMain->m_stNewbieTaskMgr.Trigger(stPlayerDetailInfoEx1._stNewbieTaskUserData, uiGID, NEWBIE_TASK_COND_1, stPlayerBaseInfo._shLevel);

    //下发系统开放数据
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(uiGID, NOTIFY_SYSOPEN_INFO);

    //好友推荐
    if (stPlayerBaseInfo._shLevel == 10
        || stPlayerBaseInfo._shLevel == 16
        || stPlayerBaseInfo._shLevel == 22
        || stPlayerBaseInfo._shLevel == 29
        || stPlayerBaseInfo._shLevel == 33)
    {
        CMainCtrl::m_pstMain->m_stFriendMgr.SendRecommendFriendList(uiGID);
    }

    //好友树祝福
    if (stPlayerBaseInfo._shLevel == 15
        || stPlayerBaseInfo._shLevel == 20
        || stPlayerBaseInfo._shLevel == 25
        || stPlayerBaseInfo._shLevel == 30
        || stPlayerBaseInfo._shLevel == 35)
    {
        CMainCtrl::m_pstMain->m_stFriendMgr.SendFriendTreeInvite(uiGID);
    } 

    //成长基金提示
    if (stPlayerDetailInfoEx1._stPayActData._ucHasBuyGrowFund == 0 
        && stPlayerBaseInfo._shLevel >= 35
        && stPlayerBaseInfo._shLevel <= 39)
    {
        CTips stTips;
        stTips._iType = 68;
        pstMainCtrl->SendTips(stPlayerBaseInfo._uiGID, stTips);
    } 
    
    bool bIsNewSalesOpen = (pstMainCtrl->m_iNow < pstMainCtrl->m_stActMgr.GetStopTime(ACT_ID_NEW_SALES));
    if (bIsNewSalesOpen && shOldLevel < NEWZONE_SALES_OPEN_LEVEL && stPlayerBaseInfo._shLevel >= NEWZONE_SALES_OPEN_LEVEL)
    {
        stPlayerBaseInfo.SetActOpen(ACT_BIT_NEWSALES1);
        pstMainCtrl->m_stActMgr.NotifyActListToRole(stPlayerBaseInfo, stPlayerDetailInfo);
    }    
}

void CCmdDropItem::HandleLevelGift (CPlayerBaseInfo & stPlayerBaseInfo, CPlayerDetailInfo & stPlayerDetailInfo,
                                    CPlayerOnlineData& stPlayerOnlineData, short shOldLevel)
{
    //是否有等级礼包可用
    int iRet = pstMainCtrl->m_stStorageMgr.CheckGiftAvail (stPlayerOnlineData._stUserStorage, stPlayerBaseInfo._uiGID);
    if (iRet)
    {
        CT_ERROR(("%d, %d, %d", stPlayerBaseInfo._uiGID, stPlayerBaseInfo._shLevel, iRet));
    }
}

void CCmdDropItem::HandleStorageGrid (CPlayerBaseInfo & stPlayerBaseInfo, CPlayerDetailInfo & stPlayerDetailInfo,
                                    CPlayerOnlineData& stPlayerOnlineData, short shOldLevel)
{
    bool bNewUnlocked = false;
    pstMainCtrl->m_stStorageMgr.UpdateGridCount (stPlayerOnlineData._stUserStorage, stPlayerBaseInfo._shLevel, bNewUnlocked);
    if (bNewUnlocked)
    {
        pstMainCtrl->m_stNotifyMgr.SendTips(stPlayerDetailInfo._uiGID, TIPS_TYPE_UNLOCKED_GRID);
    }
}

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_DROP_TO_EXSPACE, CCmdDropToExSpace);

int CCmdDropToExSpace::Do(void* pData)
{
    if (pstMainCtrl == NULL)
    {
        CT_ERROR(("mainctrl point is null"));
        return Done(RET_SYSTEM_FAIL);
    }

    if (stDropItem._astDropItem.Size() <= 0)
    {
        CT_WARNING(("drop item do nothing"));
        return Done(RET_OK);
    }

    if (uiGID == 0)
    {
        CT_ERROR(("drop item uiGID error %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdDropToExSpace::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        CT_ERROR(("drop item error , ret %d", iRet));
        return Done(iRet);
    }

    if (false == _bHaveCallBack)
    {
        pstMainCtrl->m_stItemMgr.DropItem(this, uiGID, stDropItem, false);
        return RET_OK;
    }

    //背包满了,还有物品未保存,走下面的流程

    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];
    
    //保存剩余物品
    if (true == _bHaveCallBack)
    {        
        CDropItem & stLeftItem = this->stDropItem;
        StorageData & stStorageData  = stPlayerDetailInfo._stUserStorage;
        for (int i = 0; i < stLeftItem._astDropItem.Size(); ++i)
        {
            if (stStorageData._astCommGrid.Size() < MAX_COMM_GRID_COUNT)
            {
                stStorageData._astCommGrid.AddOneItem(stLeftItem._astDropItem[i]);
            }
        }

        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = stPlayerDetailInfo._uiGID;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        //通知用户领取物品
        pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_BONUS_INFO);

        return Done(RET_OK);
    }

    return RET_OK;
}

int CCmdDropToExSpace::CallBack(int iRet)
{
    if (iRet)
    {
        CT_ERROR(("%d, %d", iRet, uiGID));
    }

    if (ID_MAIN_INNER_DROP_ITEM == m_pstChild->GetCmdID())
    {
        this->stDropItem.Clear();

        _bHaveCallBack = true;
        CCmdDropItem * pstCmd = (CCmdDropItem *)m_pstChild;        
        if (pstCmd->stLeftItem.GetSpaceSize() > 0)  //还有未完全存入的物品
        {
            this->stDropItem = pstCmd->stLeftItem;
            return LogicDo(RET_OK);
        }

        return Done(RET_OK);
    }

    return RET_OK;
}

